أعزائي ، السلام عليكم و رحمة الله و بركاته و طاب اليومكم ، 
اليوم وصلنا في دورتنا لدرسها الخامس و الذي سندرس خلاله عدد من الدوالي التي ستسمح لنا بمزيد من التعامل مع و التحكم في السلاسل النصية .
سنضع متغيران و سيرافقاننا خلال كامل الدرس ، متغير باللغة العربية و الثاني باللغة الأنجليزية .
s = "مرحبا بكم في دورة الجافا"
s1 = "welcome to this course"
قليلا من الصبر و ستفهمون لماذا إخترت في المتغير الأول الترحيب بكم في دورة الجافا و ليس البايثون.
تذكروا جيدا s و s1 الّذان سنتعامل معهما طوال هذا الدرس .
1-الدالة type() :
أول ما سنطلبه من البايثون هو أن يعرّفنا بنوع هذه المتغيرات ، من أي صنف هي ، و لمعرفة نوع أي متغير نستخدم الدالة type() حيث نضع إسم المتغير بين قوسي الدالة .
و نمر مباشرة إلى التطبيق العملي، و أذكركم أن الدالة print() تطبع لنا على الشاشة ما نضعه بين قوسيها .
print(type( s ))  
تنفيذ هذا الأمر سيطبع لكم على الشاشة ما يلي :
<class 'str'>
و هو ما يعني أن نوع متغيرنا هو str يعني stringو هو ما يمكن ترجمته للعربية بسلسلة نصية أو قطعة نصية .
الآن عرفنا نوع المتغير الذي سنتعامل معه و هذه المعرفة بنوعه ستقودنا إلى التعامل معه بدوالي معينة دون غيرها ، أكيد أننا لن نتمكن من حصر كل دوالي التعامل مع السلاسل النصية في البايثون و لكننا سنحاول الإلمام بأغلبها و أكثرها استخداما و شيوعا .
و أكيد أننا سنتعرّف على دوالي أخرى في مرحلة متقدمة من هذه الدورة أو ربما دورات أخرى .
2-الدالة replace():
الدالة replace()تقوم بإستبدال حرف أو كلمة أو أي شيء موجود داخل النص ، و هي تقبل كمعامل بين قوسيها معاملين اثنين يفصل بينهما فاصلا .
المعامل الأول هو ما نريد إستبداله أما المعامل الثاني فهو العبارة الجديدة .
ألم أقل لكم أصبروا و ستعرفون لماذا أنا رحبت بكم في دورة الجافا و ليس البايثون عندما أنشأت المتغير s الذي سنتعامل معه في درسنا هذا ، السبب هو أنني الآن سأستخدم الدالة replace لإستبدال كلمة جافا بكلمة البايثون و هذا هو الأمر الكودي الذي سيمكننا من هذا الإستبدال :
s = s.replace("الجافا","البايثون")
print( s )
و هذا ما سيطبعه البايثون على شاشاتكم :
مرحبا بكم في دورة البايثون
3- الدوالي upper-lower - title-capitalize :
الآن سندرس عدد من الدوالي للتعامل مع النصوص المكتوبة باللغة الأنجليزية أو أي لغة أخرى تكتب بنفس الحروف الأبجدية .
تذكروا المتغير s1الذي وضعناه في بداية هذا الدرس و الذي سنتعامل معه بهذه الدوالي :
upper() سيحول كل أحرف المتغير s1 الى أحرف كبيرة .
s1 = s1.upper()
print(s1)
و هذه هي نتيجة تنفيذ هذا الأمر :
WELCOME TO THIS COURSE
أما lower()فستقوم بالعكس أي ستعيد النص الذي أصبح مكتوبا بالأحرف الكبيرة إلى نص مكتوب بأحرف صغيرة .
s1 = s1.lower()
print(s1)
و هذه هي نتيجة تنفيذ هذا الأمر :
welcome to this course
أما الدالة title() فهي تحوّل كل أول حرف في كل الكلمات في نصنا إلى أحرف كبيرة .
s1 = s1.title()
print(s1)
و هذه هي نتيجة تنفيذ هذا الأمر :
Welcome To This Course
أما capitalize() فهي تحوّل الحرف الأول في الكلمة الأولى فقط إلى حرف كبير 
s1 = s1.capitalize()
print(s1)
و هذه هي نتيجة تنفيذ هذا الأمر :
Welcome to this course
4- الدالة isdigit():
هذه الدالة تتثبت إن كان المتغير المراد فحصه رقميا أم لا .
و خير مثال نورده لإستخدامات هذه الدالة هو تمريننا السابق الذي يحول المسافات بالميل إلى مسافات بالكيلومتر و في ما يلي تطبيق عملي لهذه الدالة :
ml = input("أدخل المسافة المراد تحويلها(بالميل) >:\n")
if ml.isdigit():
    ml = int(ml)
    km = 1.62 * ml
    print("المسافة بالكيلومتر تساوي", km )
else:
    print("لقد أدخلت قيمة غير صحيحة")
5- تحديد كلمات معينة داخل النص :
قلنا سابقا أن الترتيب يبدأ في لغات البرمجة من الصفر و هذه معلومة أريدكم أن لا تغفلوا عنها أبدا .
سنأخذ الآن نصنا s المكتوب بالعربية و سنتعامل معه :
إذا أردنا من البايثون أن يختار لنا عبارة " بكم"  و يطبعها لنا ، نكتب ما يلي :
print(s[6:9])
قلنا له أطبع لنا الأحرف من الحرف السابع الى الحرف التاسع ، مع الملاحظة أن الفراغ الذي نضعه بين كلمة و التي تليها يحتسب في الترتيب و يتخذ له موضعا محددا في النص .
هنا سيبدأ البايثون بالعد من أول النص كما يلي : 0 ثم 1 ثم 2 ...و هكذا الى أن يصل للموقع 6 - أي الحرف السابع -و يطبعه و يواصل في الطباعة الى أن يصل للحرف التاسع و ترتيبه 8  أذن سيطبع الاحرف ذات الترتيب 6 -7-8 و هي بكم .....لتتم طباعة الحرف 8 وضعنا داخل القوس المربع الترتيب 9 الذي تنتهي عنده الطباعة لأننا ذكرنا سابقا أن الرقم الأخير داخل الأقواس المربعة لا يؤخذ بعين الاعتبار بل يتوقف العد عند الرقم الذي يسبقه .
و هذه هي النتيجة :
بكم
الآن سنأخذ المتغير s1و هو النص المكتوب باللغة الأنجليزية :
print(s1[-6:-1])
و هذه النتيجة :
cours هنا بدأ بالعد من نهاية النص و بدأ بالحرف ذي الموقع -6 ثم توقف عند الحرف قبل الأخير فهو لم يطبع "e"و هذا طبيعي لأننا قلنا و كررنا أن العد يتوقف عند الترتيب الذي يسبق الرقم الموضوع في الاخير داخل القوس المربع .
إذن كيف يمكننا طباعة النص حتى آخره بغض النظر عن تحديدنا للبداية ؟ 
و هذا هو الحل الذي يمكننا منه صديقنا البايثون:
أن لا نضع نهاية لما نريد طباعته print(s1[-6:])
و هذا ما طبعه :
course
كما يمكننا تحديد نهاية قطعة ما بتحديد أين يتوقف البايثون دون أن نحدد البداية و في هذه الحالة سيبدأ البايثون من بداية النص رغم عدم تحديدنا لها .
print(s1[:7])
و هذه هي النتيجة :
Welcome
كيف يمكننا طباعة قطعة من النص مع القفز بحرف ، يعني طباعة الحرف الأول ثم الثالث ثم الخامس و هكذا ؟ 
و دوما حبيبنا البايثون لا يعجز عن الإستجابة لكل خيالنا الواسع و يمنحنا الحل :
print(s1[:7:2])
و هذه هي النتيجة :
Wloe
و يبدع دوما البايثون في منحنا حلولا لأفكارنا مهما بالغت في الخيال و الإستنباط، حيث يمكننا من قلب كلمة ما و ذلك بجعل "خطوة القفز" تساوي -1 فيبدأ بالحرف الأخير للكلمة و يعود للوراء بهذه الطريقة :
print(s1[:7:-1])
و هذه هي النتيجة :
esruoc siht ot
6- الدالةlen(): 
الدالة length و تكتب كوديا هكذا len() ترجع لنا طول الكائن الذي نضعه بين قوسيها كمعامل و يمكن أن يكون هذا الكائن سلسلة نصية أو من أنواع أخرى سنصلها بإذن الله في دروسنا القادمة .
سيعطينا تنفيذ الأمر التالي طول سلسلتنا النصية :
print(len(s))
و هذه هي النتيجة :
26
7- الدوالي find- rfind
سنتطرق الآن لكيفية البحث في نص معين .
سننشأ متغير نسميه search و نحدد قيمته العبارة التي نود البحث عنها .
search = "البايثون"
و ننشأ متغير آخر start نحدد قيمته بأن تكون موقع الحرف الأول في عبارة البحث ، موقعها ( أو ترتيبها ) داخل النص الذي نبحث فيه 
start = s.find(search)
print(start)
و هذه هي النتيجة :
18
قال لنا البايثون أن عبارة البايثون التي نبحث عنها في النص s تبتدىء عند النقطة 18 في النص .
العبارة التي نبحث عنها نعرفها و هي عبارة البايثون و بالتالي يمكننا نعرف طولها .
و كل عبارة - حتى تلك التي نجهلها و سيدخلها المستخدم لبرنامجنا في وقت لاحق ، يمكننا معرفة طولها بدالتنا الرائعة len() .
إذن رياضيا - من الرياضيات - و بعيدا عن البرمجة لدينا المعطيات التالية :
لدينا عبارة نعرف أين موقع بدايتها في النص 
و نعرف طولها 
اذن من البساطة بمكان أن نصل الى موقع إنتهائها في النص بإجراء العملية الحسابية البسيطة :
موقع إنتهاء عبارة البحث يساوي موقع بدايتها + طول العبارة .
هذا الكلام الرياضي نترجمه برمجيا كما يلي :
stop = start+len(search)
print(stop)
و هذه هي النتيجة:
26
الآن عرفنا أن العبارة التي نبحث عنها في نصنا ، أولا موجودة في النص ، ثانيا تبتدىء في الموقع 18 و تنتهي في الموقع 26 .
يمكننا الآن طباعتها هي كعبارة .
print(s[start:stop])
و هذه هي النتيجة :
البايثون
هذا ما تمكننا منه دالة find و هذه الدالة تبحث عن العبارة منطلقة من بداية النص و عندما تجد العبارة المطلوبة تنهي عملها ، فلو وجد في النص العبارة التي نبحث عنها أكثر من مرة في أكثر من موقع فستكتفي بإخبارنا بموقع أول عبارة تعترضها في مرورها عبر كلمات النص .
لدينا دالة شقيقتها و هي rfindو هذه تبدأ بحثها من نهاية النص و ليس بدايته بمعنى أنها ستخبرنا بموقع آخر عبارة متطابقة مع عبارة البحث التي تجدها الأخيرة اذا كان النص يحتوي على تلك العبارة أكثر من مرة .
في المثال التالي سنبحث عن حرف "ب" في نصنا s إخترته لأنه متكرر أكثر من مرة في النص .
سنبحث عنه أولا بالدالة find :
search1 = "ب"
start1 = s.find(search1)
print("ترتيب أول حرف- ب- في الجملة =" , start1)
و هذه هي النتيجة :
ترتيب أول حرف- ب- في الجملة = 3
و هذا حرف ب في عبارة "مرحبا"
ثم سنبحث عن نفس الحرف بالدالة rfind 
start2 = s.rfind(search1)
print("ترتيب آخر حرف -ب - في الجملة =" , start2)
و هذه هي النتيجة :
ترتيب آخر حرف -ب - في الجملة = 20
و هذا حرف ب في كلمة البايثون .
و هذا مثال تطبيقي للبحث في النصوص :
text = "السلام عليكم و رحمة الله و بركاته ، مرحبا بكم في دورة البايثون"
search2 = input("أدخل عبارة البحث :")
start3 = text.find(search2)
if start3 == -1:
    print("للأسف لم نجد ما تبحث عنه")
else:
    stop3 = start3 + len(search2)
    print(f"تمّالعثور على عبارة البحث بين الموقعين {start3} و{stop3} و يبلغ طول العبارة التي بحثت عنها {len(search2)}")
و هذه هي النتيجة :
في الحالة الّأولى أدخلت عبارة غير موجودة في النص و تفاعل معي البايثون و أخبرني البرنامج بأن ما أبحث عنه ليس موجودا في النص .
أدخل عبارة البحث : سليمان
للأسف لم نجد ما تبحث عنه
الدالة find عندما لا تجد عبارة البحث ترجع لنا الرقم -1 لذلك وضعت هذه القيمة في الشرط و قلت للبرنامج لو كانت نتيجة البحث تساوي -1 أي أن العبارة غير موجودة فأطبع للمستخدم الجملة "للأسف لم نجد ما تبحث عنه" 
و في الحالة الثانية بحثت عن عبارة موجودة في النص و كانت هذه هي النتيجة :
أدخل عبارة البحث :مرحبا
تمّالعثور على عبارة البحث بين الموقعين 36 و41 و يبلغ طول العبارة التي بحثت عنها 5

8- f"{}")
سأختتم درس اليوم بما قد كنتم لاحظتموه في الفقرة السابقة و الذي يخص طريقة ادخال المعامل لدالة print :
    print(f"تمّالعثور على عبارة البحث بين الموقعين {start3} و{stop3} و يبلغ طول العبارة التي بحثت عنها {len(search2)}")
فهذه الطريقة نتعرض لها لأول مرة و هي طريقة توفر علينا الكثير من الجهد .
عند ادخال المعطيات لدالة print نحن مضطرون للتفريق بين النصوص التي يتم طباعتها كنصوص و بين المتغيرات التي نرغب في طباعة قيمتها و ليست هي كنص .
التفريق بينهما يتم ب " في بداية النص و نهايته و كذلك فاصلة بين نص و متغير نريد طباعة قيمته .
بينما هذه الطريقة أبسط و أسرع إذ نكتفي بوضع المتغيرات داخل قوسين مزخرفين و نكتب باقي النص بشكل عادي .
و لترسيخ هذه الطريقة في أذهانكم سأعود لتمريننا السابق عن الميل و الكيلومتر و نطبع النتيجة بالطريقة الجديدة .

ml = input("أدخل المسافة المراد تحويلها(بالميل) >:\n")
if ml.isdigit():
    ml = int(ml)
    km = 1.62 * ml
    print(f"{ml} ميلا = {km:.3f} كلم")
else:
    print("لقد أدخلت قيمة غير صحيحة")
و هذه هي النتيجة :
أدخل المسافة المراد تحويلها(بالميل) >:
2
2 ميلا = 3.240كلم 
أريدكم أن تركزوا في دالة الطباعة هذه :
    print(f"{ml} ميلا = {km:.3f} كلم")
لقد أدخلت شيئا إضافيا جديدا لأمر الطباعة و ذلك بأن حددت عدد الأرقام العشرية (بعد الفاصلة) في نتيجة التحويل من الميل الى الكيلومتر .
و هذه هي العبارة الكودية التي تسمح لنا بذلك ، في هذا المثال طلبت من البرنامج بأن يطبع لي النتيجة ب 3 أرقام عشرية .
{km:.3f}
و في نهاية هذا الشرح الكتابي للدرس الخامس أتمنى أن أكون وفقت في كتابة كل شيء تحدّثت عنه في الدورة ، و في كل الحالات يمكنكم السؤال عن أي أمر غامض أو لم تفهموه جيدا .
وفقكم الله و تحياتي لكم جميعا .

